package zy.blue7.gui.netty.custom.qq;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import zy.blue7.gui.netty.custom.qq.codec.MessageCodec;
import zy.blue7.gui.netty.custom.qq.codec.MessageInfoCodec;
import zy.blue7.gui.netty.custom.qq.message.*;
import zy.blue7.gui.netty.custom.qq.service.MessageHandler;
import zy.blue7.gui.netty.custom.qq.service.impl.EmptyMessageHandlerImpl;
import zy.blue7.gui.netty.custom.qq.service.impl.GroupMessageHandlerImpl;
import zy.blue7.gui.netty.custom.qq.service.impl.LoginMessageHandlerImpl;
import zy.blue7.gui.netty.custom.qq.service.impl.SingleMessageHandlerImpl;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author: blue7
 * @Date: 2022/2/27 18:35
 * @Version 1.0
 * @Description
 */
public class Server {

    public static Map<String, Channel> map = new ConcurrentHashMap<>();
    public static Map<String, List<Channel>> groupMap = new ConcurrentHashMap<>();
    public static Map<Class, Object> handlerMap = new ConcurrentHashMap<>();

    static {
        handlerMap.put(SingleMessage.class, new SingleMessageHandlerImpl());
        handlerMap.put(LoginMessage.class, new LoginMessageHandlerImpl());
        handlerMap.put(GroupMessage.class, new GroupMessageHandlerImpl());
        handlerMap.put(EmptyMessage.class, new EmptyMessageHandlerImpl());
    }

    public static void main(String[] args) {

        //todo 1。启动器，负责组装 netty 组件 ，启动服务器
        new ServerBootstrap()
                //todo 2. BossGroup WOrkEventLoop(selector,thread)
                .group(new NioEventLoopGroup())
                //3 选择 服务器的 ServerSocketChannel 实现
                .channel(NioServerSocketChannel.class)
                //4。 boss负责处理链接，worker（child） 负责处理读写，决定力worker能执行哪些读写操作
                .childHandler(
                        // channel  代表和客户端进行数据读写通道    Initializer 初始化，   负责添加其他的handler
                        new ChannelInitializer<NioSocketChannel>() {

                            @Override
                            protected void initChannel(NioSocketChannel ch) throws Exception {
                                ch.pipeline().addLast(new MessageInfoCodec());
                                ch.pipeline().addLast(new MessageCodec());
//                                ch.pipeline().addLast(new MessageInfoDecoder());
//                                ch.pipeline().addLast(new MessageInfoEncoder());
                                ch.pipeline().addLast(new SimpleChannelInboundHandler<Message>() {
                                    @Override
                                    protected void channelRead0(ChannelHandlerContext channelHandlerContext, Message message) throws Exception {
                                        System.out.println(message);
                                        System.out.println(message.getClass());
                                        System.out.println("-------------------");
                                        /**
                                         * 从map中获取 指定的处理器进行处理
                                         */
                                        MessageHandler messageHandler = (MessageHandler) handlerMap.get(message.getClass());

                                        messageHandler.handle(message, ch);
                                    }

                                    @Override
                                    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
                                        ctx.channel().close();
                                    }
                                });

                            }
                        })
                .bind(8080);
    }
}

